/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.wels.sample.slice;

import com.wels.sample.ResourceTable;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;

import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.bundle.IBundleManager;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;

/**
 * DecoderAbilitySlice Class
 */
public class DecoderAbilitySlice extends AbilitySlice {
    private static final HiLogLabel TAG = new HiLogLabel(3, 0xD000F00, DecoderAbilitySlice.class.getSimpleName());

    String mStreamPath;
    String mStreamPathAuto;
    Vector<String> mStreamFiles = new Vector<String>();
    boolean hasStorageReadWritePermission = false;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_decoder);

        hasStorageReadWritePermission = checkHasStoragePermission();
        Context context = getContext();
        mStreamPath = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + "/manual_decode/";
        mStreamPathAuto = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS) + "/auto_decode/";

        Component loadComp = findComponentById(ResourceTable.Id_decoder_cfg);
        if (loadComp instanceof Button) {
            Button loadButton = (Button) loadComp;
            setClickedListerForLoadButton(loadButton);
        }

        Component autoComp = findComponentById(ResourceTable.Id_auto_decoder_button);
        if (autoComp instanceof Button) {
            Button autoDecodeButton = (Button) autoComp;
            autoDecodeButton.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    runAutoDecode();
                }
            });
        }
        Component showComp = findComponentById(ResourceTable.Id_decoder_buttonSW);
        if (showComp instanceof Button) {
            Button showButton = (Button) showComp;
            loadShowDecodeComponent(showButton);
        }
    }

    private void runAutoDecode() {
        if (hasStorageReadWritePermission) {
            runAutoDec();
        } else {
            new ToastDialog(getContext())
                    .setText("App does not have READ/WRITE permission to staorage")
                    .show();
        }
    }

    private void setClickedListerForLoadButton(Button loadButton) {
        loadButton.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                String cfgFile = mStreamPath + "BitStreams.txt";
                if (hasStorageReadWritePermission) {
                    readfile(cfgFile);
                } else {
                    new ToastDialog(getContext())
                            .setText("App does not have READ/WRITE permission to staorage").show();
                }
            }
        });
    }

    private void readfile(String cfgFile) {
        try(BufferedReader bufferedReader = new BufferedReader(new FileReader(cfgFile))) {
            String text;
            while ((text = bufferedReader.readLine()) != null) {
                mStreamFiles.add(mStreamPath + text);
                HiLog.info(TAG, mStreamPath + text);
            }
        } catch (IOException e) {
            HiLog.error(TAG, e.getMessage());
        }
    }

    private void loadShowDecodeComponent(Button showButton) {
            showButton.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    HiLog.info(TAG, "decode sequence number = " + mStreamFiles.size());
                    if (hasStorageReadWritePermission) {
                        loadStreamFiles();
                    } else {
                        new ToastDialog(getContext())
                                .setText("App does not have READ/WRITE permission to staorage")
                                .show();
                    }
                }
            });
    }

    private void loadStreamFiles() {
        for (int k = 0; k < mStreamFiles.size(); k++) {
            String inFile = mStreamFiles.get(k);
            String outFile =  mStreamFiles.get (k) + ".yuv";
            DoDecoderTest(inFile, outFile);
        }
        mStreamFiles.clear();
    }

    private boolean checkHasStoragePermission() {
        return verifySelfPermission("ohos.permission.READ_USER_STORAGE") == IBundleManager.PERMISSION_GRANTED &&
                verifySelfPermission("ohos.permission.WRITE_USER_STORAGE") == IBundleManager.PERMISSION_GRANTED;
    }

    /**
     * runAutoDec
     */
    public void runAutoDec() {
        Thread thread = new Thread() {
            /**
             * run
             */
            public void run() {
                HiLog.info(TAG, "decoder performance test begin");

                File bitstreams = new File (mStreamPathAuto);
                String[] list = bitstreams.list();
                if (list == null || list.length == 0) {
                    HiLog.info(TAG, "have not find any coder resourse");
                    terminate();
                }
                for (int i = 0; i < list.length; i++) {
                    String inFile = list[i];
                    inFile = mStreamPathAuto + inFile;
                    String outFile = inFile + ".yuv";
                    DoDecoderTest (inFile, outFile);
                }
                HiLog.info(TAG, "decoder performance test finish");
            }
        };
        thread.start();
    }

    /**
     * DoDecoderTest
     *
     * @param infilename infilename
     * @param outfilename outfilename
     */
    public native void  DoDecoderTest (String infilename, String outfilename);

    static {
            System.loadLibrary ("openh264");
            System.loadLibrary ("stlport_shared");
            System.loadLibrary ("decoding");
            HiLog.info(TAG, "Load libwelsdec successful");
    }
}
